package org.yourscrum.web.story;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.yourscrum.domain.Story;
import org.yourscrum.domain.Task;
import org.yourscrum.service.BacklogService;

/**
 * @author Jettro Coenradie
 */
@Controller
@RequestMapping("/story/**/task/**")
public class TaskController {
    @Autowired
    private BacklogService backlogService;

    /* All task related methods */
    @RequestMapping(value = "/story/{storyId}/task/form", method = RequestMethod.GET)
    public String createTaskForm(@PathVariable("storyId") Long storyId, ModelMap modelMap) {
        Assert.notNull(storyId, "Story Identifier must be provided.");
        TaskVO task = new TaskVO(storyId);
        modelMap.addAttribute("task", task);
        return StoryController.VIEW_STORY_TASK_FORM;
    }


    @RequestMapping(value = "/story/{storyId}/task/{id}", method = RequestMethod.GET)
    public String showTasks(@PathVariable("storyId") Long storyId,
                            @PathVariable("id") Long id,
                            ModelMap modelMap) {
        Assert.notNull(storyId, "Story identifier must be provided.");
        Assert.notNull(id, "Identifier must be provided.");
        modelMap.addAttribute("story", backlogService.obtainStoryById(storyId));
        return StoryController.VIEW_STORY_TASK_SHOW;
    }

    @RequestMapping(value = "/story/{storyId}/task/{id}/form", method = RequestMethod.GET)
    public String updateTaskForm(@PathVariable("storyId") Long storyId,
                                 @PathVariable("id") Long id,
                                 ModelMap modelMap) {
        Assert.notNull(storyId, "Story Identifier must be provided.");
        Assert.notNull(id, "Task Identifier must be provided.");
        Story story = backlogService.obtainStoryById(storyId);
        Task existingTask = null;
        for (Task currentTask : story.getTasks()) {
            if (currentTask.getId().equals(id)) {
                existingTask = currentTask;
                break;
            }
        }
        TaskVO task = new TaskVO(storyId);
        if (existingTask != null) {
            task.setId(id);
            task.setActualHours(existingTask.getActualHours());
            task.setDescription(existingTask.getDescription());
            task.setEstimatedHours(existingTask.getEstimatedHours());
        }
        modelMap.addAttribute("task", task);
        return StoryController.VIEW_STORY_TASK_FORM;
    }

    @RequestMapping(value = "/story/{storyId}/task", method = RequestMethod.POST)
    public String addOrUpdateTask(@PathVariable("storyId") Long storyId,
                                  @ModelAttribute("task") TaskVO task,
                                  BindingResult result) {
        Assert.notNull(storyId, "Story Identifier must be provided.");
        Assert.notNull(task, "A task instance must be provided");
        new TaskValidator().validate(task, result);
        if (result.hasErrors()) {
            return StoryController.VIEW_STORY_TASK_FORM;
        } else {
            if (task.getId() == null) {
                this.backlogService.addTaskToStory(storyId, task.getDescription(), task.getEstimatedHours());
            } else {
                // TODO jettro : implement this
                throw new RuntimeException("Oops task id is not null _" + task.getId() + "_ and updates are not supported yet");
            }
            return StoryController.REDIRECT_STORY_LIST;
        }

    }
}
